﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Globalization;
using BlueLotus7.ArchiveSystem.Common;
using BlueLotus7.ArchiveSystem.Interfaces;
using System.Threading;
using BlueLotus7.ArchiveSystem.WCFClients;
using BlueLotus7.ExternalApi.TencentStatusApi;

namespace BlueLotus7.ArchiveSystem
{
    public abstract class StatusMonitorTask : IStatusMonitorTask
    {
        #region Fields

        protected int interval;

        protected StatusMonitor statusMonitor = null;

        protected Thread runningThread = null;

        #endregion

        #region Properties

        public bool Running
        {
            get;
            set;
        }

        public Guid Key
        {
            get;
            set;
        }

        public string ThirdPartyIdentity
        {
            get;
            set;
        }

        public Guid DomainScopeUserKey
        {
            get;
            set;
        }

        #endregion

        #region Constructor

        public StatusMonitorTask(Guid domainScopeUserKey, string thirdPartyIdentity, StatusMonitor monitor, int interval)
        {
            this.statusMonitor = monitor;
            this.DomainScopeUserKey = domainScopeUserKey;
            this.ThirdPartyIdentity = thirdPartyIdentity;
            this.Key = Guid.NewGuid();

            this.interval = interval;
            if (interval < 1000)
            {
                //10 seconds
                interval = 10000;
            }
        }

        #endregion

        #region IStatusMonitorTask

        public void Start()
        {
            if (runningThread == null)
            {
                runningThread = new Thread(new ThreadStart(this.Execute));
                runningThread.IsBackground = true;
                this.Running = true;
                runningThread.Start();
            }
        }

        public virtual void Stop()
        {
            this.Running = false;
        }

        #endregion

        #region Protected Methods

        protected virtual void Execute()
        {
            Global.Logger.LogMessageWithTimestamp(string.Format("Start to execute monitor task Code: {0}, Identity: {1}.", this.statusMonitor.ScopeCode, this.ThirdPartyIdentity));

            while (this.Running)
            {
                try
                {
                    int status = RetrieveStatus();
                    ReportStatus(status);
                }
                catch (Exception ex)
                {
                    Global.Logger.LogException(
                        new Exception(
                            string.Format("Fail to execute monitor task Code: {0}, Identity: {1}.", this.statusMonitor.ScopeCode, this.ThirdPartyIdentity),
                            ex));
                }

                Thread.Sleep(this.interval);
            }

            Global.Logger.LogMessageWithTimestamp(string.Format("Task to monitor Code: {0}, Identity: {1} is disposed.", this.statusMonitor.ScopeCode, this.ThirdPartyIdentity));
        }

        protected virtual int RetrieveStatus()
        {
            return 0;
        }

        protected virtual void ReportStatus(int status)
        {
            using (ArchiveStatusServiceClient client = Global.ServiceClient)
            {
                bool needSyncUsers = client.ReportStatus(this.statusMonitor.MonitorClientKey, this.statusMonitor.DomainScopeKey, this.DomainScopeUserKey, status);
                if (needSyncUsers)
                {
                    this.statusMonitor.UpdateSyncStamp();
                }
            }
        }

        #endregion
    }
}
